home *** CD-ROM | disk | FTP | other *** search
- UNIT adap_mod;
-
- {$O+}
-
- { ------------------------------------------------------------------
-
- This program and its associates implement in Turbo Pascal v5
- the aritmetic encoding/decoding algorithms presented in the papers
-
- "Arithmetic Coding for Data Compression"
-
- by Ian H. Witten
- Radford M. Neal
- John G. Cleary
-
- pp 520 - 540 of June 1987 Communications of the ACM
-
- and
-
- "An Adaptive Dependency Source Model For Data Compression"
-
- by David M. Abrahamson
-
- pp 77 - 83 of January 1989 Communications of the ACM
-
- ------------------------------------------------------------------
-
- Implemented by Ken Westerback : CompuServe 73547,3520
-
- version 1.0 released 89/02/19
- version 2.0 released 89/02/27
-
- These programs, units and associated documentation are released
- into the public domain to be used and abused as your whims
- dictate.
-
- Feel free to distribute/incorporate/improve as desired.
-
- >>>>> Use at your own risk! <<<<<
-
- Comments and suggestions welcome via CompuServe.
-
- ------------------------------------------------------------------
- }
-
- INTERFACE
-
-
- const model_name = 'Adaptive Model';
-
- { this procedure initializes the model - must be exported cuz we }
- { may be overlay'ed }
-
- procedure start_model;
-
- function select_char ( symbol : integer ) : char;
-
- function select_symbol ( ch : char ) : integer;
-
- procedure update_model ( symbol : integer );
-
-
- IMPLEMENTATION uses model_h;
-
- { make these arrays dynamic so multiple model overlays will not }
- { use up unnecessary memory, or worse, use the same memory for }
- { different things! }
-
- type ctoi_array = array [ 0..no_of_chars-1 ] of integer;
- itoc_array = array [ 0..no_of_symbols ] of char;
-
- ctoi_p = ^ctoi_array;
- itoc_p = ^itoc_array;
-
- var char_to_index : ctoi_p; { to index from character }
- index_to_char : itoc_p; { to character from index }
-
-
- procedure start_model;
-
- var i : integer;
-
- begin
-
- new ( char_to_index );
- new ( index_to_char );
-
- { set up tables that translate between symbol indexes and }
- { characters }
-
- for i := 0 to no_of_chars-1 do
- begin
- char_to_index^[ i ] := i + 1;
- index_to_char^[ i+1 ] := chr ( i );
- end;
-
- { set up initial frequency counts to be one for all symbols }
-
- for i := 0 to no_of_symbols do
- begin
- freq [ i ] := 1;
- cum_freq[ i ] := no_of_symbols - i;
- end;
-
- { freq[ 0 ] must not be the same as freq[ 1 ] }
-
- freq[ 0 ] := 0;
-
- end;
-
- function select_symbol ( ch : char ) : integer;
-
- begin
-
- select_symbol := char_to_index^[ ord(ch) ];
-
- end; { select symbol }
-
-
- function select_char ( symbol : integer ) : char;
-
- begin
-
- select_char := index_to_char^[ symbol ];
-
- end; { select_char }
-
-
- procedure update_model ( symbol : integer );
-
- var i, cum, ch_i, ch_symbol : integer;
-
- begin
-
- { see if frequency counts are at their maximum. if they are }
- { then halve all counts, keeping them non-zero }
-
- if ( cum_freq[ 0 ] = max_frequency ) then
- begin
- cum := 0;
- for i := no_of_symbols downto 0 do
- begin
- freq[ i ] := ( freq[ i ] + 1 ) div 2;
- cum_freq[ i ] := cum;
- inc ( cum, freq[ i ] );
- end;
- end;
-
- { find symbol's new index }
-
- i := symbol;
- while freq[ i ] = freq[ i-1 ] do dec ( i );
-
- { update the translation tables if the symbol has moved }
-
- if ( i < symbol ) then
- begin
-
- ch_i := integer ( index_to_char^[ i ] );
- ch_symbol := integer ( index_to_char^[ symbol ] );
-
- index_to_char^[ i ] := chr ( ch_symbol );
- index_to_char^[ symbol ] := chr ( ch_i );
-
- char_to_index^[ ch_i ] := symbol;
- char_to_index^[ ch_symbol ] := i;
-
- end;
-
- { increment the frequency count for the symbol and update }
- { the cumulative frequencies }
-
- inc ( freq[ i ] );
-
- while ( i > 0 ) do
- begin
- dec ( i );
- inc ( cum_freq[ i ] );
- end;
-
- end; { update_model }
-
-
- END. { adaptive model implementation }